package com.xiaoluo.a14_banner.banner;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Scroller;
import android.widget.Toast;


import com.bumptech.glide.Glide;
import com.xiaoluo.a14_banner.R;
import com.xiaoluo.a14_banner.banner.indicator.BaseIndicator;
import com.xiaoluo.a14_banner.banner.indicator.CircleIndicator;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import static android.view.Gravity.BOTTOM;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;

/**
 * <b>Project:</b> https://github.com/GitHubZJY/ZJYWidget <br>
 * <b>Create Date:</b> 2018/8/31 <br>
 * <b>@author:</b> Yang <br>
 * <b>Description:</b> 自定义Banner轮播View <br>
 */
public class BannerView extends FrameLayout {
    private static final String TAG = "BannerView";

    private BaseIndicator mIndicator;
    private static final long DELAY_TIME = 3000;
    private List<Integer> mBannerUrlList;
    private InnerPagerAdapter mAdapter;
    private int mCurrentIndex = 0;
    private final static int PLAY = 0x123;
    private boolean mGestureScroll = false;
    private int mPageMargin = 40;

    private Handler mHandler = new BannerHandler(this);
    private float mBannerRadius = 20;


    private static class BannerHandler extends Handler {
        WeakReference<BannerView> mBannerViewWeakReference;

        public BannerHandler(BannerView view) {
            mBannerViewWeakReference = new WeakReference<>(view);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == PLAY) {
                BannerView view = mBannerViewWeakReference.get();
                if (view != null && view.mBannerViewPager != null) {
                   // view.mBannerViewPager.setCurrentItem(view.mCurrentIndex);
                    //   view.mCurrentIndex++;
                   // sendEmptyMessageDelayed(PLAY, DELAY_TIME);
                }
            }
        }
    }

    public BannerView(Context context) {
        this(context, null);
    }

    public BannerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BannerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init() {
        initBannerView();
        initViewPager();
        initIndicatorView();
    }

    private void initBannerView() {
        setClipChildren(false);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        setLayoutParams(params);
    }

    private float downX;
    private float downY;
    private float upX;
    private float upY;
    private long downTime;
    private long upTime;

    private ViewPager mBannerViewPager = new ViewPager(getContext()) {
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN: {
                    downTime = System.currentTimeMillis();
                    downX = ev.getRawX();
                    downY = ev.getRawY();
                    Log.i(TAG, "dispatchTouchEvent:  x:" + downX + "  y:" + downY + "current:" + mCurrentIndex);
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    upTime = System.currentTimeMillis();
                    upX = ev.getRawX();
                    upY = ev.getRawY();
                    if (upTime - downTime < 500 && Math.abs(upX - downX) < 50) {
                        if (downX < UiUtil.div(520) && downX < UiUtil.div(520)) {
                            Log.i(TAG, "dispatchTouchEvent: 520click index:" + (mCurrentIndex - 1) % mBannerUrlList.size());
                        } else if (downX < UiUtil.div(1360) && downY < UiUtil.div(1360)) {
                            Log.i(TAG, "dispatchTouchEvent: 1360click index" + mCurrentIndex % mBannerUrlList.size());
                        } else {
                            Log.i(TAG, "dispatchTouchEvent: 1920click index" + (mCurrentIndex + 1) % mBannerUrlList.size());
                        }
                    }
                    break;
                }
                default:
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }
    };

    private void initViewPager() {
        LayoutParams bannerParams = new LayoutParams(800, 465);
        bannerParams.gravity = CENTER;
        bannerParams.setMargins(mPageMargin, 0, mPageMargin, 0);
        addView(mBannerViewPager, bannerParams);
        mBannerViewPager.addOnPageChangeListener(mPageListener);
        mBannerUrlList = new ArrayList<>();
        mAdapter = new InnerPagerAdapter();
        mBannerViewPager.setAdapter(mAdapter);
        mBannerViewPager.setCurrentItem(Integer.MAX_VALUE / 2);
        mBannerViewPager.setOffscreenPageLimit(3);
        mBannerViewPager.setPageMargin(mPageMargin);
        mBannerViewPager.setClipChildren(false);
        changeScrollSpeed();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        return mBannerViewPager.dispatchTouchEvent(ev);
    }


    private void changeScrollSpeed() {
        try {
            Field mScroller = null;
            mScroller = ViewPager.class.getDeclaredField("mScroller");
            mScroller.setAccessible(true);
            FixedSpeedScroller scroller = new FixedSpeedScroller(getContext(), new DecelerateInterpolator());
            mScroller.set(mBannerViewPager, scroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化指示器
     */
    private void initIndicatorView() {
        mIndicator = new CircleIndicator(getContext());
        LayoutParams indicatorParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 60);
        indicatorParams.gravity = BOTTOM | CENTER_HORIZONTAL;
        addView(mIndicator, indicatorParams);
    }

    public void setIndicator(BaseIndicator indicator) {
        removeView(mIndicator);
        mIndicator = indicator;
        LayoutParams indicatorParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 60);
        indicatorParams.gravity = BOTTOM | CENTER_HORIZONTAL;
        addView(mIndicator, indicatorParams);
        invalidate();
    }

    /**
     * ViewPager滑动监听
     */
    ViewPager.OnPageChangeListener mPageListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            if (position == 0 || mBannerUrlList.isEmpty()) {
                return;
            }
            setScrollPosition(position);
            int smallPos = position % mBannerUrlList.size();
            mIndicator.setCurrentPosition(smallPos);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            onPageScrollStateChange(state);
        }
    };


    public void setBannerData(List<Integer> bannerData) {
        mBannerUrlList.clear();
        mBannerUrlList.addAll(bannerData);
        mAdapter.notifyDataSetChanged();
        //   startPlay();
        mIndicator.setCellCount(bannerData.size());
    //    mCurrentIndex = bannerData.size() / 2;
        mBannerViewPager.setCurrentItem(8);

    }


    public void startPlay() {
        play();
    }

    private void play() {
        //      mHandler.sendEmptyMessageDelayed(PLAY, mDelayTime);
    }


    /**
     * 手指滑动时暂停自动轮播，手指松开时重新启动自动轮播
     *
     * @param state
     */
    private void onPageScrollStateChange(int state) {
        switch (state) {
            case ViewPager.SCROLL_STATE_IDLE:
                if (!mGestureScroll) {
                    return;
                }
                mGestureScroll = false;
                mHandler.removeMessages(PLAY);
                mHandler.sendEmptyMessageDelayed(PLAY, 100);
                break;
            case ViewPager.SCROLL_STATE_DRAGGING:
                mGestureScroll = true;
                mHandler.removeMessages(PLAY);
                break;
            default:
                break;
        }
    }


    private void setScrollPosition(int position) {
        mCurrentIndex = position;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mHandler.removeMessages(PLAY);
    }

    private class InnerPagerAdapter extends PagerAdapter {

        public InnerPagerAdapter() {
        }

        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            CardView cardView = new CardView(getContext());
            cardView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            cardView.setCardElevation(5);
            cardView.setRadius(mBannerRadius);

            ImageView bannerIv = new ImageView(getContext());
            bannerIv.setScaleType(ImageView.ScaleType.CENTER_CROP);
            bannerIv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            int size = mBannerUrlList.size();
            if (size == 0) {
                return bannerIv;
            }
            position %= size;
            if (position < 0) {
                position = size + position;
            }
            Glide.with(getContext()).load(mBannerUrlList.get(position)).into(bannerIv);
            cardView.addView(bannerIv);
            container.addView(cardView);
            return cardView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }

    public static class FixedSpeedScroller extends Scroller {
        private int mDuration = 500;

        public FixedSpeedScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, mDuration);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy) {
            super.startScroll(startX, startY, dx, dy, mDuration);
        }
    }

}
